using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace net.notdot.Attercop.Client
{
    public partial class SearchWindow : Form
    {
        private ClientInstance c;
        private Query q;

        private class MediaType
        {
            private string m_Name;
            public string Name
            {
                get
                {
                    return m_Name;
                }
            }

            private string m_MimeType;
            public string MimeType
            {
                get
                {
                    return m_MimeType;
                }
            }

            private bool? m_IsDir;
            public bool? IsDir
            {
                get
                {
                    return m_IsDir;
                }
            }

            public MediaType(string name, string mime, bool? isDir)
            {
                m_Name = name;
                m_MimeType = mime;
                m_IsDir = isDir;
            }
        }

        public SearchWindow(ClientInstance c)
        {
            InitializeComponent();
            this.c = c;
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            lstResults.Items.Clear();

            long minSize = -1;
            long maxSize = -1;
            MediaType type = (MediaType)cmbType.SelectedItem;

            if(q != null) {
                c.CancelSearch(q);
                q = null;
            }

            if (txtSize.Text == "")
            {
                minSize = maxSize = -1;
            }
            else
            {
                long multiplier = (long) Math.Pow(1024, cmbSizeMagnitude.SelectedIndex);

                switch (cmbSizeConstraint.SelectedIndex)
                {
                    case 0: //At most
                        maxSize = long.Parse(txtSize.Text) * multiplier;
                        minSize = -1;
                        break;
                    case 1: //Exactly
                        minSize = long.Parse(txtSize.Text) * multiplier;
                        minSize = (long.Parse(txtSize.Text) + 1) * multiplier - 1;
                        break;
                    case 2: //At least
                        maxSize = -1;
                        minSize = long.Parse(txtSize.Text) * multiplier;
                        break;
                }
            }
            
            q = c.Search(txtSearch.Text, minSize, maxSize, type.MimeType, type.IsDir, new EventHandler<MessageEventArgs<SearchResultMessage>>(q_Search));
        }

        private void q_Search(object sender, MessageEventArgs<SearchResultMessage> args) {
            Invoke(new EventHandler<MessageEventArgs<SearchResultMessage>>(q_SearchEx), new object[] { sender, args });
        }

        private void q_SearchEx(object sender, MessageEventArgs<SearchResultMessage> args)
        {
            foreach (SearchResult result in args.Message.Results)
            {
                string extension = Path.GetExtension(result.Filename);

                ((MainWindow)MdiParent).AddFileIcon(extension);

                string[] fields = new string[] { 
                    Path.GetFileName(result.Filename),
                    PathNode.GetHumanSize(result.Size),
                    args.Message.Sender.Nick,
                    "",
                    Path.GetDirectoryName(result.Filename)
                };

                if (!result.IsDir)
                {
                    lstResults.Items.Add(new ListViewItem(fields, extension));
                }
                else
                {
                    lstResults.Items.Add(new ListViewItem(fields, 0));
                }
            }
        }

        private void SearchWindow_Load(object sender, EventArgs e)
        {
            cmbType.Items.Add(new MediaType("Any", "", null));
            cmbType.Items.Add(new MediaType("Audio", "audio/", false));
            cmbType.Items.Add(new MediaType("Binary", "application/", false));
            cmbType.Items.Add(new MediaType("Text", "text/", false));
            cmbType.Items.Add(new MediaType("Image", "image/", false));
            cmbType.Items.Add(new MediaType("Video", "video/", false));
            cmbType.Items.Add(new MediaType("Directory", "", true));
            cmbType.SelectedIndex = 0;

            lstResults.SmallImageList = ((MainWindow)MdiParent).imlSmallFileIcons;
        }
    }
}